#pragma once
#include <vector>
#include <cstring>
#include <string>
#include <iostream>
#include "typedefs.h"

using namespace std;

class SymbolTuple;
class ResultClauseTuple;
class RelationTuple;
class WithClauseTuple;
class PatternTuple;

class Symbol{
public:
	
	Symbol();
	~Symbol();
	symbolIndex insertSymbol(SymbolTuple* tuple);
	design_entity getSymbolType(symbolIndex index);
	string getSymbolName(symbolIndex index);
	symbolIndex searchSymbolName(string name);
	vector<symbolIndex> searchSymbolType(design_entity type);
	SymbolTuple getSymbolTupleAt(symbolIndex index);

	int getSize();
private:
	int count;
	vector<SymbolTuple> symbolTable;

};

class Result {
public:
	Result();
	~Result();
	void insertResult(ResultClauseTuple* tuple);
	void insertBooleanResult();
	//resultIndex insertResult(ResultClauseTuple* tuple);
	/*resultIndex insertBooleanResult(bool result);
	resultIndex insertSymbolResult(Symbol result);
	resultIndex insertTupleResult(vector<Symbol> result);*/		// need a case for a.procName type of result
	bool isBooleanResult();
	/*vector<Symbol> getSymbolResult();
	vector<vector<Symbol>> getTupleResult();*/
	vector<ResultClauseTuple> getAllResult();
	int getSize();
	ResultClauseTuple getResultClauseTupleAt(int index);
	
private:
	int count;
	bool booleanResult;
	vector<ResultClauseTuple> resultList;
	//vector<Result*> resultTable;

};

class Relation{
public:
	Relation();
	~Relation();
	void insertRelation(RelationTuple* tuple);
	//relationIndex insertRelation(RelationTuple tuple);
	//string getRelationRef(relationIndex index);
	//int* getArgs(relationIndex index);

	vector<RelationTuple> getAllRelation();
	int getSize();
	RelationTuple getRelationTupleAt(int index);
private:
	vector<RelationTuple> relationList;
	int count;
};

class WithClause{
public:
	WithClause();
	~WithClause();
	/*withClauseIndex insertWithClause(Symbol type, string attrName, string ref);
	
	Symbol getSymbol(withClauseIndex index);
	string getAttrName(withClauseIndex index);
	int getRef(withClauseIndex index);

	vector<withClauseIndex> searchSymbol(Symbol targetSymbol);*/
	void insertWithClause(WithClauseTuple* tuple);
	vector<WithClauseTuple> getAllWith();
	int getSize();
	WithClauseTuple getWithClauseTupleAt(int index);

private:
	vector<WithClauseTuple> withList;
	int count;
};

class Pattern{
public:
	Pattern();
	~Pattern();
	patternIndex insertPattern(Symbol type, string entRef, string subExpression );
	
	Symbol getSymbol(patternIndex index);
	string getEntRef(patternIndex index);
	string getSubExpression(patternIndex index);

	vector<patternIndex> searchSymbol(Symbol targetSymbol);
	int getSize();

private:
	vector<Pattern*> patternTable;	
};


